package frame.dao;

import java.util.List;
import java.util.Map;


/**
 * 所有的关系维系都是靠 约定的 表字段 对象属性映射，当查询结果列为单列时，如果尝试
 * 将查询结果映射到bean的操作失败时，尝试将查询结果映射为单个基本类型。
 * 最终映射的结果由传入的类对象指引。
 * 最终数据的结果由传入的sql语句指引。
 * @author Mr.CuiPeng
 *
 */
public interface DAO {

	/**
	 * 根据所给sql创建一个prepared statement并将传入的参数集合绑定上去，并执行查询语句。
	 * 期望的查询结果为单独的一行多列或是只有一行一列的单一值。如果参数中指定的类型不是基本类型
	 * 则查询结果会被按列名=属性的关系映射到这个类型的对象上返回。如果参数中指定的类型是基本类型
	 * 比如：String,int,long... 则查询结果必须是是一行一列，单一结果将被转换为所给对象返回。
	 * @param sql 查询语句
	 * @param t 查询结果的对象类型
	 * @param args 查询参数
	 * @return 对象类型所指的对象。
	 * @Throws IncorrectResultSizeDataAccessException - 如果查询返回的结果不是一行或是无法正确的转换为所给类型的对象
	 *         DataAccessException - 查询失败了。
	 */
	public <T> T queryObject(String sql,Class<T> t,Object... args);
	/**
	 * 根据所给sql创建一个prepared statement并将传入的参数集合绑定上去，并执行查询语句。
	 * 期望的查询结果为单独的一行，结果会被转换为一个MAP对象返回。一个键值对为一列，用列名作为键。
	 * 这个方法被设计为如果你无法为查询结果找到一个合适的领域模型时使用，否则请考虑使用queryObject()
	 * @param sql 查询语句
	 * @param args 查询参数
	 * @return 包含查询结果的map对象。
	 * @Throws IncorrectResultSizeDataAccessException - 如果查询返回的结果返回多行。
	 *         DataAccessException - 查询失败了。
	 */
	public Map<String,Object> queryMap(String sql,Object... args) ;
	/**
	 * 根据所给sql创建一个prepared statement并将传入的参数集合绑定上去，并执行查询语句。
	 * 查询结果会被映射到一个list中，元素为参数中指定的对象类型。结果中的每一行会被转换为一个单独
	 * 的对象。如果参数中指定的类型不是基本类型,则每一行会被按列名=属性的关系映射到这个类型的对象上
     * 插入到集合中。如果参数中指定的类型是基本类型 比如：String,int,long... 则查询结果必须只有
     * 一列，每一行将被转换为所给对象插入到集合。
	 * @param sql 查询语句
	 * @param t 查询结果的对象类型
	 * @param args 查询参数
	 * @return 包含对象类型所指的对象集合。
	 * @Throws  DataAccessException - 查询失败了。
	 */
    public <T> List<T> queryObjectList(String sql, Class<T> t,Object... args);
	/**
	 * 根据所给sql创建一个prepared statement并将传入的参数集合绑定上去，并执行查询语句。
	 * 查询结果会被映射为包含map(一个键值对对应一列，列名作为键)对象的List(每一行作为集合中的一个元素)集合。
	 * @param sql 查询语句
	 * @param args 查询参数
	 * @return 一个包含了map(每行一个)对象的集合
	 * @Throws  DataAccessException - 查询失败了。
	 */
	public  List<Map<String, Object>> queryMapList(String sql,Object... args);
	
	/**
	 * 执行一个SQL更新操作(比如：insert,update 或者 delete 语句)
	 * 通过 prepared statement 绑定所给的参数。参数的绑定方式为
	 * 通过第三个参数order数组中的元素(其实是第二个参数的中的key值)的顺序
	 * 来决定sql语句要绑定的参数的顺序。
	 * @param sql 更新语句
	 * @param data 包含更新参数的map对象
	 * @param order sql 语句中？占位符需要的第二个参数data中的key的顺序。
	 * @return 所影响的行数。
	 * @throws DataAccessException - 执行更新语句失败。
	 */
	public  int updateMap(String sql,Map<String,?> data,String... order) ;
	
	/**
	 * 执行一个SQL更新操作(比如：insert,update 或者 delete 语句)
	 * 通过 prepared statement 绑定所给的参数。参数的绑定方式为
	 * 通过第三个参数order数组中的元素(其实是第二个参数的中的属性名)的顺序
	 * 来决定sql语句要绑定的参数的顺序。
	 * @param sql 更新语句
	 * @param data 包含更新参数的domain对象
	 * @param order sql 语句中？占位符需要的第二个参数data中的属性的顺序。
	 * @return 所影响的行数。
	 * @throws DataAccessException - 执行更新语句失败。
	 */
    public  <T> int updateObject(String sql,T data,String... order);
    
    /**
	 * 执行一个SQL更新操作(比如：insert,update 或者 delete 语句)
	 * 通过 prepared statement 绑定所给的参数。这个方法直接来自
	 * jdbcTemplet.update(String sql,Object...args)
	 * @param sql 更新语句
	 * @param args 更新参数
	 * @return 所影响的行数。
	 * @throws DataAccessException - 执行更新语句失败。
	 */
    public int update(String sql,Object...args);
    
    /**
	 * 执行一个不带参数的SQL更新操作(比如：insert,update 或者 delete 语句)
	 * 这个方法直接来自 jdbcTemplet.update(String sql)
	 * @param sql 更新语句
	 * @return 所影响的行数。
	 * @throws DataAccessException - 执行更新语句失败。
	 */
    public int update(String sql);
    
    /**
	 * 执行一个SQL更新操作(比如：insert,update 或者 delete 语句)
	 * 通过 prepared statement 绑定所给的参数。这个方法直接来自 
	 * jdbcTemplet.update(String sql,Object[] args,int[] argTypes)
	 * @param sql 更新语句
	 * @param args 更新参数
	 * @param argTypes SQL types of the arguments (constants from java.sql.Types)
	 * @return 所影响的行数。
	 * @throws DataAccessException - 执行更新语句失败。
	 */
    public int update(String sql,Object[] args,int[] argTypes);
  
    /**
	 * 对sql的处理方式与参数绑定方式见 
	 * updateMap(String sql,Map<String,?> data,String... order)的说明。
	 * 这个方法处理的数据为一个包含了map对象的list集合。该方法的更新方式是batchUpdate。
	 * 如果要将包含map对象的集合更新的数据库建议使用这个方法。
	 * @param sql 更新语句
	 * @param data 更新的参数集合
	 * @param order sql 语句中？占位符需要的第二个参数data中的key的顺序。
	 * @return 被每个更新语句所影响的行数的数组。
	 * @throws DataAccessException - 执行更新语句失败。
	 */
    public  int[] updateMaps(String sql,List<Map<String,Object>> data,String... order);

    /**
	 * 对sql的处理方式与参数绑定方式见 
	 * updateObject(String sql,T data,String... order)的说明。
	 * 这个方法处理的数据为一个包含了domain对象的list集合。该方法的更新方式是batchUpdate。
	 * 如果要将包含map对象的集合更新的数据库建议使用这个方法。
	 * @param sql 更新语句
	 * @param data 更新的参数集合
	 * @param order sql 语句中？占位符需要的第二个参数data中的key的顺序。
	 * @return 被每个更新语句所影响的行数的数组。
	 * @throws DataAccessException - 执行更新语句失败。
	 */
    public  <T> int[] updateObjects(String sql,List<T> data,String... order);
    
    /**
	 * 查询分页信息，该功能能够根据sql和args参数的摘要信息缓存总页数，如果是相同的摘要信息，则不执行
	 * 总页数查询语句。
	 * @param pageInfo 分页对象中包含的对象的类信息。
	 * @param sql 数据库查询语句
	 * @param pageStart 第几页
	 * @param pageSize 每页多少条记录
	 * @param args 查询条件
	 * @return 分页好的分页信息
	 */
	public <T> Page<T> paginate(Class<T> pageInfo,String sql,int pageStart,int pageSize,String sort,String sortD,Object... args);

    
}